<template>
    <div class="page"></div>
</template>
<script>
import * as d3 from "d3"
import logoImg from "@/assets/logo.png"
const PERDEG = Math.PI / 180
export default {
    created() {
        this.config = {
            margins: { top: 30, left: 30, bottom: 30, right: 30 }, //距离边框的padding值
            totalAngle: 180, //总共要画的角度
            width: 80, //内圆环和外圆环的半径差值
            colors: d3.schemeCategory10,
            title: "参与者总数",
            data: {
                //数据
                total: 10,
                detail: [
                    {
                        name: "普通车辆",
                        count: 3,
                    },
                    {
                        name: "轻型卡车",
                        count: 1,
                    },
                    {
                        name: "卡车",
                        count: 1,
                    },
                    {
                        name: "摩托车",
                        count: 1,
                    },
                    {
                        name: "公交车",
                        count: 1,
                    },
                    {
                        name: "紧急车辆",
                        count: 1,
                    },
                    {
                        name: "行人",
                        count: 1,
                    },
                    {
                        name: "自行车",
                        count: 1,
                    },
                ],
            },
        }
    },
    methods: {
        draw() {
            this.init()
        },
        init() {
            //初始化svg画布的一些参数
            let container = this.$el
            this.svgWidth = container.clientWidth
            this.svgHeight = container.clientHeight
            //计算弧形的半径
            this.chartRadius =
                d3.min([
                    this.svgWidth -
                        this.config.margins.left -
                        this.config.margins.right,
                    this.svgHeight -
                        this.config.margins.top -
                        this.config.margins.bottom,
                ]) / 2
            this.svg = d3
                .select(this.$el)
                .append("svg")
                .attr("width", this.svgWidth)
                .attr("height", this.svgHeight)
            //平移到 元素的中心点位置  ============= 这里可能还需要进一步的计算（因为有padding参数）
            this.arcChart = this.svg
                .append("g")
                .attr(
                    "transform",
                    `translate(${this.svgWidth / 2},${
                        (this.svgHeight / 4) * 3
                    })`
                )
            //计算每一段弧长的起始角度
            let { detail, total } = this.config.data,
                drawAngles = []
            detail.reduce((prev, next) => {
                let startAngle = prev,
                    endAngle =
                        prev +
                        (next.count / total) * this.config.totalAngle * PERDEG
                drawAngles.push({
                    startAngle,
                    endAngle,
                })
                return endAngle
            }, (-this.config.totalAngle / 2) * PERDEG)
            let innerRadius =
                this.chartRadius - this.config.width > 0
                    ? this.chartRadius - this.config.width
                    : 10
            //设置弧形生成器
            let arc = d3
                .arc()
                .innerRadius(innerRadius)
                .outerRadius(this.chartRadius)
            //画 弧形
            let groupArc = this.arcChart
                .selectAll("g")
                .data(drawAngles)
                .join("g")
            groupArc
                .append("path")
                .attr("d", (d, i) => arc(d, i))
                .attr("stroke", "none")
                .attr("id", (d, i) => {
                    return `arc${i}`
                })
                .attr("fill", (d, i) => this.config.colors[i])
            groupArc
                .append("image")
                .attr("xlink:href", logoImg)
                .attr("width", "10")
                .attr("height", "10")
                .attr("transform", d => {
                    let point = arc.centroid(d)
                    return `translate(${[point[0] - 5, point[1] - 5]})`
                })
            //添加弧形的说明文字
            arc.innerRadius(this.chartRadius + 20).outerRadius(
                this.chartRadius + 20
            )
            groupArc
                .append("text")
                .attr("x", (d, i) => {
                    let point = arc.centroid(d, i)
                    return point[0]
                })
                .attr("y", (d, i) => {
                    let point = arc.centroid(d, i)
                    return point[1]
                })
                .attr("fill", "#000")
                .text((d, i) => this.config.data.detail[i].name)
                .attr("text-anchor", "middle")
            arc.innerRadius(this.chartRadius + 40).outerRadius(
                this.chartRadius + 40
            )
            //添加弧形的说明文字
            groupArc
                .append("text")
                .attr("x", (d, i) => {
                    let point = arc.centroid(d, i)
                    return point[0]
                })
                .attr("y", (d, i) => {
                    let point = arc.centroid(d, i)
                    return point[1]
                })
                .attr("dy", -10)
                .attr("fill", "#000")
                .text("21%")
                .attr("text-anchor", "middle")
            //画内部的圆环
            arc.innerRadius(innerRadius - 10).outerRadius(innerRadius)
            groupArc
                .append("path")
                .attr("d", (d, i) => arc(d, i))
                .attr("stroke", "none")
                .attr("fill", (d, i) => this.config.colors[i])
            arc.innerRadius(this.chartRadius + 20).outerRadius(
                this.chartRadius + 20
            )
            //画最内层的圆弧线
            arc.innerRadius(innerRadius - 20).outerRadius(innerRadius - 20)
            groupArc
                .append("path")
                .attr("d", (d, i) => arc(d, i))
                .attr("stroke", "red")
                .attr("fill", "none")
            this.arcChart
                .append("text")
                .text(this.config.data.total)
                .attr("text-anchor", "middle")
            this.arcChart
                .append("text")
                .text(this.config.title)
                .attr("text-anchor", "middle")
                .attr("dy", "20")
        },
    },
    mounted() {
        this.draw()
    },
}
</script>
<style scoped>
.page {
    width: 100%;
    height: 400px;
}
</style>